/*
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.util;

import java.util.function.UnaryOperator;

/**
 * @see Collection
 * @see Set
 * @see ArrayList        动态数组实现，支持随机访问
 * @see LinkedList       双向链表实现，只能顺序访问，但是可以快速地在链表中间插入和删除元素。不仅如此，LinkedList 还可以用作栈、队列和双向队列。
 * @see Vector           ArrayList 类似，但它是线程安全的
 *
 * @see Arrays#asList(Object[])
 * @see Collections#nCopies(int, Object)
 * @see Collections#EMPTY_LIST
 * @see AbstractList
 * @see AbstractSequentialList
 * @since 1.2
 */

public interface List<E> extends Collection<E> {


    // Query Operations

    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();

    Object[] toArray();

    <T> T[] toArray(T[] a);


    // Modification Operations

    boolean add(E e);

    boolean remove(Object o);


    // Bulk Modification Operations

    boolean containsAll(Collection<?> c);

    boolean addAll(Collection<? extends E> c);

    boolean addAll(int index, Collection<? extends E> c);

    boolean removeAll(Collection<?> c);

    boolean retainAll(Collection<?> c);

    void clear();


    // Comparison and hashing

    boolean equals(Object o);

    int hashCode();

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }


    /**
     * 使用指定的操作符替换列表中的每个元素
     * 此方法用于对列表中的每个元素应用给定的 unary operator（一元操作符）进行转换，并将转换后的结果替换原元素
     *
     * @param operator 应用于列表中每个元素的一元操作符，不能为空
     *                 注意：此方法要求操作符不能为空，以避免在执行过程中遇到空指针异常
     *                 使用 ListIterator 而不是简单的 for 循环，是因为 ListIterator 可以在遍历过程中安全地设置元素
     */
    default void replaceAll(UnaryOperator<E> operator) {
        // 确保提供的操作符不为空
        Objects.requireNonNull(operator);
        // 获取列表的 ListIterator，以便在遍历过程中设置元素
        final ListIterator<E> li = this.listIterator();
        // 遍历列表中的每个元素
        while (li.hasNext()) {
            // 对当前元素应用操作符并设置回列表
            li.set(operator.apply(li.next()));
        }
    }


    /**
     * 使用给定的比较器对列表进行排序
     * 此方法通过将列表转换为数组，使用Arrays.sort方法对数组进行排序，然后将排序后的数组内容
     * 重新设置回列表，从而实现对列表的排序
     *
     * @param c 用于比较列表中元素的比较器，它决定了列表排序的顺序
     *          比较器的类型参数为列表元素类型的父类型，允许使用更通用的比较逻辑
     */
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();        // 将列表转换为数组，以便使用Arrays.sort进行排序
        Arrays.sort(a, (Comparator) c);     // 使用给定的比较器对数组进行排序
        ListIterator<E> i = this.listIterator(); // 获取列表的列表迭代器，以便后续更新列表元素
        // 遍历排序后的数组，将每个元素更新到列表中
        for (Object e : a) {
            // 移动到下一个元素位置
            i.next();
            // 将当前位置的元素替换为排序后数组中的元素
            i.set((E) e);
        }
    }


    // Positional Access Operations



    /**
     * 将此列表中指定位置的元素替换为指定的元素（可选操作）。
     *
     * @param index   要替换的元素的索引
     * @param element 要存储在指定位置的元素
     * @return 指定位置之前的元素
     * @throws UnsupportedOperationException 如果此列表不支持 <tt>set</tt> 操作
     * @throws ClassCastException            如果指定元素的类阻止其被添加到此列表中
     * @throws NullPointerException          如果指定元素为 null 且此列表不允许 null 元素
     * @throws IllegalArgumentException      如果指定元素的某些属性阻止其被添加到此列表中
     * @throws IndexOutOfBoundsException     如果索引超出范围
     *                                       (<tt>index &lt; 0 || index &gt;= size()</tt>)
     */
    E set(int index, E element);

    /**
     * 在此列表的指定位置插入指定元素（可选操作）。将当前位于该位置的元素（如果有）以及后续的所有元素向右移动（索引加一）。
     *
     * @param index   要插入指定元素的位置
     * @param element 要插入的元素
     * @throws UnsupportedOperationException 如果此列表不支持 <tt>add</tt> 操作
     * @throws ClassCastException            如果指定元素的类阻止其被添加到此列表中
     * @throws NullPointerException          如果指定元素为 null，并且此列表不允许 null 元素
     * @throws IllegalArgumentException      如果指定元素的某些属性阻止其被添加到此列表中
     * @throws IndexOutOfBoundsException     如果索引超出范围
     *                                       (<tt>index &lt; 0 || index &gt; size()</tt>)
     */
    void add(int index, E element);


    /**
     * 从列表中移除指定位置的元素（可选操作）。将后续元素向左移动（索引减一）。返回被移除的元素。
     *
     * @param index 要移除的元素的索引
     * @return 被移除的元素
     * @throws UnsupportedOperationException 如果此列表不支持移除操作
     * @throws IndexOutOfBoundsException     如果索引超出范围
     *                                       (<tt>index &lt; 0 || index &gt;= size()</tt>)
     */
    E remove(int index);


    // Search Operations

    /**
     * 返回此列表中首次出现的指定元素的索引，如果此列表不包含该元素，则返回 -1。
     * 更正式地说，返回最低索引 <tt>i</tt> 使得
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>，
     * 如果没有这样的索引，则返回 -1。
     *
     * @param o 要搜索的元素
     * @return 此列表中首次出现的指定元素的索引，如果此列表不包含该元素，则返回 -1
     * @throws ClassCastException   如果指定元素的类型与此列表不兼容
     *                              （<a href="Collection.html#optional-restrictions">可选</a>）
     * @throws NullPointerException 如果指定的元素为 null 且此列表不允许 null 元素
     *                              （<a href="Collection.html#optional-restrictions">可选</a>）
     */
    int indexOf(Object o);


    /**
     * 返回此列表中最后一次出现指定元素的索引，如果此列表不包含该元素，则返回 -1。
     * 更正式地说，返回最高的索引 <tt>i</tt>，使得
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>，
     * 如果没有这样的索引，则返回 -1。
     *
     * @param o 要搜索的元素
     * @return 此列表中最后一次出现指定元素的索引，如果此列表不包含该元素，则返回 -1
     * @throws ClassCastException   如果指定元素的类型与此列表不兼容
     *                              （<a href="Collection.html#optional-restrictions">可选</a>）
     * @throws NullPointerException 如果指定的元素为 null 且此列表不允许 null 元素
     *                              （<a href="Collection.html#optional-restrictions">可选</a>）
     */
    int lastIndexOf(Object o);


    // List Iterators

    /**
     * 返回一个列表迭代器，用于遍历此列表中的元素（按正确的顺序）。
     *
     * @return 一个列表迭代器，用于遍历此列表中的元素（按正确的顺序）
     */
    ListIterator<E> listIterator();

    /**
     * 返回一个列表迭代器，用于从指定位置开始遍历此列表中的元素（按正确的顺序）。
     * 指定的索引表示通过初始调用 {@link ListIterator#next next} 方法将返回的第一个元素。
     * 初始调用 {@link ListIterator#previous previous} 方法将返回索引减一的元素。
     *
     * @param index 列表迭代器将返回的第一个元素的索引（通过调用 {@link ListIterator#next next}）
     * @return 一个列表迭代器，用于从指定位置开始遍历此列表中的元素（按正确的顺序）
     * @throws IndexOutOfBoundsException 如果索引超出范围（{@code index < 0 || index > size()}）
     */
    ListIterator<E> listIterator(int index);

    // 视图

    /**
     * 返回此列表中指定范围内的子列表视图。范围包括 <tt>fromIndex</tt>（包含），但不包括 <tt>toIndex</tt>（不包含）。
     * （如果 <tt>fromIndex</tt> 和 <tt>toIndex</tt> 相等，则返回的列表为空。）
     * 返回的列表由这个列表支持，因此返回的列表中的非结构化更改会反映在原始列表中，反之亦然。
     * 返回的列表支持此列表支持的所有可选列表操作。<p>
     * <p>
     * 此方法消除了显式范围操作的需要（通常数组中存在此类操作）。任何期望列表的操作都可以通过传递子列表视图而不是整个列表来作为范围操作。
     * 例如，以下惯用法可以删除列表中的一段元素：
     * <pre>{@code
     *      list.subList(from, to).clear();
     * }</pre>
     * 类似的惯用法可以构造用于 <tt>indexOf</tt> 和 <tt>lastIndexOf</tt>，并且 <tt>Collections</tt> 类中的所有算法都可以应用于子列表。<p>
     * <p>
     * 如果此列表（即支持列表）以任何方式被结构化修改（除通过返回的列表外），则返回的列表的语义变得未定义。
     * （结构化修改是指改变此列表大小或以其他方式扰乱列表，导致正在进行的迭代可能产生错误结果的操作。）
     *
     * @param fromIndex 子列表的低端点（包含）
     * @param toIndex   子列表的高端点（不包含）
     * @return 指定范围内的子列表视图
     * @throws IndexOutOfBoundsException 如果端点索引值非法
     *                                   （<tt>fromIndex &lt; 0 || toIndex &gt; size ||
     *                                   fromIndex &gt; toIndex</tt>）
     */
    List<E> subList(int fromIndex, int toIndex);


}
